import * as Form from "@radix-ui/react-form"
import { FormEvent, forwardRef, useCallback } from "react"
import UiButton from "./UiButton"

export type UiFormRootProps = React.PropsWithChildren<{
    onSubmit?: (data: { [key in string]: FormDataEntryValue }) => void
}>
export const UiFormRoot = forwardRef<HTMLFormElement, UiFormRootProps>(({
    children,
    onSubmit
}: UiFormRootProps, ref) => {
    const onFinish = useCallback((e: FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        const data = Object.fromEntries(new FormData(e.currentTarget));
        if (!!onSubmit) onSubmit(data);
    }, [onSubmit]);
    return (
        <Form.Root
            onSubmit={onFinish}
            ref={ref}
        >
            {children}
        </Form.Root>
    )
})


export type UiFormSubmit = React.PropsWithChildren<{
    className?: string
}>
export const UiFormSubmit = forwardRef<HTMLButtonElement, UiFormSubmit>(({
    children,
    className
}, ref) => {
    return (
        <Form.Submit asChild className={className}>
            <UiButton ref={ref}>
                {children}
            </UiButton>
        </Form.Submit>
    )
})

export type UiFormItemProps = React.PropsWithChildren<{
    name: string,
    className?: string,
    valueMissing?: string,
    typeMismatch?: string,
    label?: string,
    match?: (value: string, formData: any) => boolean,
    matchMessage?: string,
    serverErrorMessage?: string,
    required?: boolean
}>
export const UiFormItem = ({
    children,
    name,
    className = "grid mb-[10px]",
    valueMissing,
    typeMismatch,
    label,
    matchMessage,
    match,
    serverErrorMessage,
    required = false
}: UiFormItemProps) => {
    return (
        <Form.FormField
            name={name}
            className={className}
        >
            <div className="flex items-baseline justify-between">
                {!!label && <Form.FormLabel className="text-[15px] font-medium leading-[35px] ">{label}</Form.FormLabel>}
                {!!valueMissing && <Form.FormMessage className="text-[13px] opacity-[0.8]" match="valueMissing">
                    {valueMissing}
                </Form.FormMessage>}
                {!!typeMismatch && <Form.FormMessage className="text-[13px] opacity-[0.8]" match="typeMismatch">
                    {typeMismatch}
                </Form.FormMessage>}
                {(!!match && !!matchMessage) && <Form.FormMessage className="text-[13px] opacity-[0.8]" match={match}>
                    {matchMessage}
                </Form.FormMessage>}
                {!!serverErrorMessage && <Form.FormMessage className="text-[13px] opacity-[0.8]">
                    {serverErrorMessage}
                </Form.FormMessage>}
            </div>
            <Form.FormControl asChild required={required} >
                {children}
            </Form.FormControl>
        </Form.FormField >
    )
}